#pragma once


#include "Object.h"
#include "SQLObject.h"
#include "SQLObjectImpl.h"
#include "SQLExpr.h"
#include "SQLOrderBy.h"
// #include "../visitor/SQLASTVisitor.h"
#include "../visitor/VisitorFeature.h"
#include "SQLStatement.h"
#include "SQLCommentHint.h"

#include "../../DbType.h"
#include "../../Exception/UnsupportedOperationException.h"

// import com.alibaba.druid.sql.SQLUtils;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

class SQLStatementImpl : virtual public SQLObjectImpl, virtual public SQLStatement
{
public:
  SQLStatementImpl();
  virtual ~SQLStatementImpl();

  SQLStatementImpl(DbType_ptr dbType);
  DbType_ptr getDbType();
  void setDbType(DbType_ptr dbType);
  string_ptr toString(VisitorFeature_list_ptr features);

  string_ptr toString();

  DbType_ptr dbType;
  BOOL_ptr afterSemi;
  SQLCommentHint_list_ptr headHints;

  SHAREDOBJECT(SQLStatementImpl) ;
  virtual SQLObject_ptr getParent() { return NULL; };

  virtual void setParent(SQLObject_ptr parent){};

  // virtual std::map<string_ptr , Object_ptr > &getAttributes()
  // {
  //   std::map<string_ptr , Object_ptr > x;
  //   return x;
  // };

  // virtual Object_ptr getAttribute(string_ptr name) { return NULL; };

  // virtual void putAttribute(string_ptr name, Object_ptr value){};

  // virtual std::map<string_ptr , Object_ptr > &getAttributesDirect()
  // {
  //   std::map<string_ptr , Object_ptr > x;
  //   return x;
  // };

  virtual void output(std::stringstream * buf){};

  virtual string_ptr getClass()
  {
    return make_string_ptr("SQLStatementImpl");
  }

  SQLCommentHint_list_ptr getHeadHintsDirect()
  {
    return headHints;
  }
  void setHeadHints(SQLCommentHint_list_ptr headHints_)
  {
    for (auto it : *headHints_)
    {
      this->headHints->push_back(it);
    }
  }
  virtual bool containsAttribute(string_ptr name) {return false;}
  virtual void addBeforeComment(string_list_ptr comments){};
  virtual void addBeforeComment(wstring_list_ptr comments){};
  virtual string_list_ptr getBeforeCommentsDirect(){};
  virtual void addAfterComment(string_ptr comment){};
  virtual void addAfterComment(string_list_ptr comments){};
  virtual void addAfterComment(wstring_list_ptr comments){};
  virtual string_list_ptr getAfterCommentsDirect(){};
  virtual bool hasBeforeComment(){return false;};
  virtual bool hasAfterComment(){return false;};
  virtual SQLObject_ptr clone()
  {
    throw new UnsupportedOperationException(this->getClass());
  }
protected:
  virtual void accept0(SQLASTVisitor_ptr visitor) override;
};

